#include<iostream>
#include<dirent.h>
#include<sys/stat.h>
#include<errno.h>
#include<string.h>
#include<unistd.h>
#include<string>

using namespace std;

//函数声明部分
string Validpath(string);
void dir_Tidy(DIR*, struct dirent*,string argv);
string get_extension(string);
string get_target_path(string, string);
string get_source_path(string, string);
int make_DIR(string);
int is_directory(string);

//main函数主体
int main(int argc, char* argv[])
{
        //首先判断main函数参数是否有且仅有一条路径
        if(argc < 2)
        {
                cout<<"ERROR！PLEASE USE \"./bin/file_manager /complete/path/of/directory1 /complete/path/of/directory2 ...\""<<endl;
                return -1;
        }


        for(int i = 0; i < argc - 1; i++)
        {
		//再对main函数参数中的文件路径作处理（主要是末尾的'/')
		string valid_path = Validpath(argv[i + 1]);

                //创建DIR结构体的指针，它储存着目录内所有文件的信息
                DIR* dir;
                if( (dir = opendir(argv[i + 1])) == nullptr )
                {
                        cout<<"ERROR:" << argv[i + 1] << "  :PLEASE CHECK AND MAKE SURE YOUR PATH IS VALID"<<endl;
                        continue;
                }

                struct dirent* entry = nullptr;

                dir_Tidy(dir,entry,valid_path);
		closedir(dir);
        }
        return 0;
}


//函数实现部分//

//处理main函数参数路径的函数
string Validpath(string argv)
{
	if(argv.back() == '/')return argv;
	return argv + '/';
}

//对目录中所有文件进行整理的一系列操作
void dir_Tidy(DIR* dir, struct dirent* entry, string argv)
{
        while( (entry = readdir(dir)) != nullptr )
        {
                //获取扩展名
                string ex_name = get_extension(entry->d_name);

                //拼接扩展名文件夹路径以及源文件路径 
                //
                //扩展名文件夹路径 = argv + ex_name;
                string target_path = argv + ex_name ;
                //
                //源文件路径 = argv + d_name
                string source_path = argv + entry->d_name;

                if(is_directory(source_path))continue;//如果文件是目录，则不作操作
                make_DIR(target_path);//创建目录

                //目标路径 = 扩展名文件夹路径 + 文件名
                target_path += entry->d_name;

                if(rename(source_path.c_str(), target_path.c_str()) == 0)
                {
                        cout<<source_path<<" SUCCESSFULLY MOVED TO "<<target_path<<endl;
                }
                else
                {
                        cout<<source_path<<" UNSUCCESSFULLY MOVED TO "<<target_path<<endl;
                }

        }
}

//获取扩展名的函数
string get_extension(string name)
{
	if(name.find('.') == string::npos) return "others/";

	if(name.find('.') == 0) return "";

        string dot = name.substr(name.find('.') + 1,name.length());

        return dot + '/';
}


//创建目录及相关操作的函数
int make_DIR(string path)
{
        if(mkdir(path.c_str(),0755) == 0) return 0;

        if(errno == EEXIST) return 0;
        else
        {
                cout<<"FAILED TO CREATE DIRECTORY:"<<path<<endl;
                return -1;
        }
}

//判断文件是否为目录的函数
int is_directory(string path)
{
        struct stat statbuf;
        if(stat(path.c_str(),&statbuf)!=0)return 0;

        return S_ISDIR(statbuf.st_mode);
}
